﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Queue;
using Microsoft.WindowsAzure.Storage.Blob;
using System.Reflection;
using System.Diagnostics;
using Microsoft.WindowsAzure.Storage.Table.DataServices;
using System.Collections.Specialized;
using wlog.Shell.Storage.Table;
using wlog.Shell.Storage.Queue;
using wlog.Shell.Storage.Blob;
using POC.Azure.Storage;
using POC.Configuration;
namespace wlog.Shell.Storage
{   
    public class StorageCommand : Command
    {     
        //  Must be replaced by cache
        static AzureAccount _account = null;
        public StorageCommand(bool isLocal = true)
        {
            try
            {
                string useProxy = AppSetting.Instance["UseSystemProxy"]; 
                GetAccount(isLocal);
            }
            catch (Exception azureEx)
            {
                Results.WriteLine("Error ccreating table {0} ", azureEx.Message);
            }
        }
        public static AzureAccount GetAccount(bool isLocal)
        {          
            if (_account == null)
                _account = new AzureAccount(isLocal);
            
            return _account;
        }
      
        //protected string objectSource;
        //protected string objectInstanceUri;
        private StorageCommand _internalCommand;

      

        public override void Setup(string[] args)
        {
            try
            {
                TokenizeCommand(args);               
            }
            catch (IndexOutOfRangeException exc)
            {
                Results.Add("Insufficent arguments passed.");
            }
        }
        public CloudTableClient GetTableAccount()
        {
            return _account.CloudAccount.CreateCloudTableClient();
        }
        public CloudQueueClient GetQueueAccount()
        {
            return _account.CloudAccount.CreateCloudQueueClient();
        }
        public CloudBlobClient GetBlobAccount()
        {
            return _account.CloudAccount.CreateCloudBlobClient();
        }
        public AzureAccount GetSetUpAccount()
        {          
              return StorageCommand._account;
        }

        public virtual StorageCommand ResolveCommand()
        {
            switch (commandVerb)
            {               
                case K.commandtype_list:
                    switch (commandObjectType)
                    {
                        //  it is a TableStorageCommand
                        case K.commandname_table:
                            _internalCommand = new TableListCommand();
                            break;
                        //TODO
                        case K.commandname_queue:
                            _internalCommand = new QueueListCommand();
                            break;
                        //TODO
                        case K.commandname_blob:
                            _internalCommand = new BlobListCommand();
                            break;
                        default:
                            _internalCommand = this;
                            break;
                    }
                    break;
                case K.commandtype_get:
                case K.commandtype_select:
                case K.commandtype_peek:
                case K.commandtype_pull:
                case K.commandtype_dequeue:
                case K.commandtype_read:
                    switch (commandObjectType)
                    {
                        //  it is a TableStorageCommand
                        case K.commandname_table:
                            if (K.commandtype_select == commandVerb)
                            {
                                _internalCommand = new TableSelectCommand();
                            }
                            else
                            {
                                _internalCommand = new TableGetCommand();
                            }
                            break;
                        //TODO
                        case K.commandname_queue:
                            if (K.commandtype_peek == commandVerb || K.commandtype_read == commandVerb)
                            {
                                _internalCommand = new QueueGetCommand(false);
                            }
                            else
                            {
                                _internalCommand = new QueueGetCommand(true);
                            }
                            break;
                        //TODO
                        case K.commandname_blob:
                            _internalCommand = new BlobGetCommand();
                            break;
                        default:
                            _internalCommand = this;
                            break;
                    }
                    break;
                case K.commandtype_insert:           
                case K.commandtype_add:
                case K.commandtype_post:   
                case K.commandtype_push :
                case K.commandtype_enqueue:
                    switch (commandObjectType)
                    {
                        //  it is a TableStorageCommand
                        case K.commandname_table:
                            _internalCommand = new TableInsertCommand();
                            break;
                        //TODO
                        case K.commandname_queue:
                            _internalCommand = new QueuePushCommand();
                            break;
                        //TODO
                        case K.commandname_blob:
                            _internalCommand = new BlobCreateCommand();
                            break;
                        default:
                            _internalCommand = this;
                            break;
                    }
                    break;
                case K.commandtype_create:
                    switch (commandObjectType)
                    {
                        //  it is a TableStorageCommand
                        case K.commandname_table:
                            _internalCommand = new TableCreateCommand();
                            break;
                        //TODO
                        case K.commandname_queue:
                            _internalCommand = new QueueCreateCommand();
                            break;
                        //TODO
                        case K.commandname_blob:
                            _internalCommand = new BlobCreateCommand();
                            break;
                        default:
                            _internalCommand = this;
                            break;
                    }
                    break;
                case K.commandtype_option:
                    switch (commandObjectType)
                    {
                        //  it is a TableStorageCommand
                        case K.commandname_table:
                            _internalCommand = new TableOptionsCommand();
                            break;
                        //TODO
                        case K.commandname_queue:
                            _internalCommand = new QueueOptionsCommand();
                            break;
                        //TODO
                        case K.commandname_blob:
                            _internalCommand = new BlobOptionsCommand();
                            break;
                        default:
                            _internalCommand = this;
                            break;
                    }
                    break;
                case K.commandtype_put:
                case K.commandtype_upload:
                case K.commandtype_update:
                case K.commandtype_write:
                    switch (commandObjectType)
                    {
                        //  it is a TableStorageCommand
                        case K.commandname_table:
                            _internalCommand = new TableUpdateCommand();
                            break;
                        //TODO
                        case K.commandname_queue:
                            _internalCommand = new QueueUpdateCommand();
                            break;
                        //TODO
                        case K.commandname_blob:
                            _internalCommand = new BlobUpdateCommand();
                            break;
                        default:
                            _internalCommand = this;
                            break;
                    }
                    break;
                case K.commandtype_delete:
                    switch (commandObjectType)
                    {
                        //  it is a TableStorageCommand
                        case K.commandname_table:
                            _internalCommand = new TableDeleteCommand();
                            break;
                        //TODO
                        case K.commandname_queue:
                            _internalCommand = new QueueDeleteCommand();
                            break;
                        //TODO
                        case K.commandname_blob:
                            _internalCommand = new BlobDeleteCommand();
                            break;
                        default:
                            _internalCommand = this;
                            break;
                    }
                    break;
                default:
                    _internalCommand = this;
                    break;
            }
            _internalCommand.Setup( CommandArgs);
            return _internalCommand;
        }
    }

}
